<?php
defined('IN_APP') or exit('Access Denied');

class core
{
	private static $_imports;
	
	private static $_instances;
	
	public static function run(){
		include APP_ROOT.'source/libs/functions.php';  //
		self::init_env();
		self::init_input();
		
		self::init_output();
		self::init_route();
		include APP_ROOT.'config/url.php';//载入URL规则
		try{
			self::load_controller();
		}catch(Exception $e){
// 			srv_log_service::log_exception(ROUTE_M, ROUTE_C, ROUTE_A, $e);
// 			throw $e;
			var_dump($e);
		}
		self::echo_debug();
	}
	
	public static function init_service(){
		self::init_env(false);
		include_once APP_ROOT.'config/url.php';//载入URL规则
	}
	
	private static function echo_debug(){
		if(HRLOO_DEBUG === 1){
			//echo '======DebugInfo==========<br/>',"\n";
			fx_log::echo_log();
		}
	}
	
	/**
	 * 初始化环境
	 * @return boolean
	 */
	private static function init_env($set_err_hand=true){
		//(自动加载类)向下兼容php低版本
		if(function_exists('spl_autoload_register')) {
			spl_autoload_register(array('core', 'autoload')); //注册core类中的autoload为自动加载的方法
		} else {
			function __autoload($class) {
				return core::autoload($class);
			}
		}
		
		if(!$set_err_hand) return;//服务调用时不需要设置
		
		set_exception_handler(array('core', 'handleException'));  //设置一个用户定义的异常处理函数。
		
		if(APP_DEBUG === 1) {
			set_error_handler(array('core', 'handleError')); //设置一个用户定义的错误处理函数
			register_shutdown_function(array('core', 'handleShutdown'));
		}
		
	}
	
	/**
	 * 初始化输入
	 * 关闭MAGIC_QUOTES_GPC
	 */
	private static function init_input(){
		if(get_magic_quotes_gpc()) {
			$_POST = fx_utl::stripslashes($_POST);
			$_GET = fx_utl::stripslashes($_GET);
			$_REQUEST = fx_utl::stripslashes($_REQUEST);
			$_COOKIE = fx_utl::stripslashes($_COOKIE);
		}
		
		if(isset($_GET['page'])) {
			$_GET['page'] = max(intval($_GET['page']),HPAGE_MIN);
			$_GET['page'] = min(intval($_GET['page']),HPAGE_MAX);
		}
	}
	
	private static function init_output(){
		header('Content-Type:text/html; charset=UTF-8');
	}
	
	private static function init_route(){
		global $DEFAULT_ROUTE;
		$config = $HDEFAULT_ROUTE;
		$m = isset($_GET['m']) && !empty($_GET['m']) ? $_GET['m'] : (isset($_POST['m']) && !empty($_POST['m']) ? $_POST['m'] : $config['m']);
		$m =$_GET['m'] = $_POST['m'] =  self::safe_route($m);
		
		$c = isset($_GET['c']) && !empty($_GET['c']) ? $_GET['c'] : (isset($_POST['c']) && !empty($_POST['c']) ? $_POST['c'] : $config['c']);
		$c = $_GET['c'] = $_POST['c'] = self::safe_route($c);
		
		$a = isset($_GET['a']) && !empty($_GET['a']) ? $_GET['a'] : (isset($_POST['a']) && !empty($_POST['a']) ? $_POST['a'] : $config['a']);
		$a = $_GET['a'] = $_POST['a'] = self::safe_route($a);
		
		define('ROUTE_M', $m);
		define('ROUTE_C', $c);
		define('ROUTE_A', $a);
	}
	
	private static function safe_route($str){
		return str_replace(array('/', '.'), '', $str);
	}
	
	private static function load_controller(){
		global $PUBLISHING_PAGE;
		if($PUBLISHING_PAGE)
		{
			$publishkey=ROUTE_M.'||'.ROUTE_C.'||'.ROUTE_A;
			if(isset($PUBLISHING_PAGE[$publishkey]))
			{
				header("Location: ".$PUBLISHING_PAGE[$publishkey]); 
				exit;
			}
		}
		$class = ROUTE_C;
		$action = ROUTE_A;
		$filepath = APP_ROOT.'source/modules/'.ROUTE_M.'/'.ROUTE_C.'.php';
		$exists = include $filepath;
		if(!$exists) exit('Access Denied!code:file'); //文件不存在
		if(!class_exists(ROUTE_C))  exit('Access Denied!code:model'); //controller 不存在
		$ctl = new $class;
		if (!method_exists($ctl, ROUTE_A)) exit('Access Denied!code:action');//action 不存在
		if (strpos(trim(ROUTE_A),'_') === 1) exit('Access Denied!code:act prv');//访问私有Action
		if($_GET["fromtg"]){
			fx_utl::savecookie("HRFROMTG",$_GET["fromtg"]); //TODO 这是什么东西
		}
		$ctl->$action();
	}
	
	
	public static function autoload($class) {
		$class = strtolower($class);
		if(strpos($class, '_') !== false) {
			$folders=explode('_', $class);
			$folder1=$folders[0];
			$folder2=isset($folders[1])?$folders[1]:'';
			$folder3=isset($folders[2])?$folders[2]:'';
			if($folder1 === 'fx'){
				$file = $folder3 ?FX_ROOT.$folder2.'/'.$class.'.php' : FX_ROOT.$class.'.php';
			}else if($folder1 === 'srv'){
				$file = $folder3 ? SRV_ROOT.$folder2.'/'.$class.'.php' : SRV_ROOT.$class.'.php';
			}else if($folder1 === 'm'){
				$file = APP_ROOT.'source/model/'.$class.'.php';
			}
		} else {
			$file = APP_ROOT.'source/libs/'.$class.'.php';
		}
		try {
			self::import($file);
			return true;
		} catch (Exception $exc) {
			$trace = $exc->getTrace();
			foreach ($trace as $log) {
				if(empty($log['class']) && $log['function'] == 'class_exists') {
					return false;
				}
			}
			self::handleException($exc);
		}
	}
	
	/**
	 * 载入TAG
	 * @param string $module
	 * @return object
	 */
	public static function loadtag($module){
		$classname = $module.'_tag';
		return self::load_module_classes($module, $classname);
	}
	/**
	 * 载入module下的classes
	 * @param unknown_type $module
	 * @param unknown_type $classname
	 */
	public static function load_module_classes($module,$classname)
	{		
		$key=$module.'-'.$classname;
		if(isset(self::$_instances[$key])){
			return self::$_instances[$key];
		}		
		$file = HAPP_MODULES_ROOT."$module/classes/$classname".".php";
		self::import($file);
		$instance = new $classname;		
		self::$_instances[$key] = $instance;
		return $instance;
	}
	public static function import($filename,$force=false) {
		$name = $key = $filename;
		if(!isset(self::$_imports[$key])) {
			if(is_file($name)) {
				self::$_imports[$key] = true;
				return include_once $name;
			} elseif(!$force) {
				return false;
			} else {
				throw new Exception('import failed: '.$filename);
			}
		}
		return true;
	}
	
	/**
	 * 设置启用Memcached存储Session
	 */
	public static function setMemSessionHandler(){
		global $HMEMCACHED;
		$pathlist= array();
		
		foreach($HMEMCACHED as $cfg){
			$pathlist[] = "tcp://{$cfg['server']}:{$cfg['port']}?persistent={$cfg['pconnect']}&weight={$cfg['weight']}&timeout={$cfg['timeout']}";
		}
		
		ini_set('memcache.hash_function','crc32');
		ini_set('memcache.hash_strategy','consistent');
		
		ini_set('session.save_handler', 'memcache');
		ini_set("session.save_path", join(',',$pathlist));
	}
	
	
	public static function handleException($exception) {
		if(APP_DEBUG === 1){
			$error=$exception;
			//调试模式下输出错误信息
			if (!is_array($error)) {
				$trace = debug_backtrace();
				$e['message'] = $error;
				$e['file'] = $trace[0]['file'];
				$e['class'] = $trace[0]['class'];
				$e['function'] = $trace[0]['function'];
				$e['line'] = $trace[0]['line'];
				$traceInfo = '';
				$time = date('y-m-d H:i:m');
				foreach ($trace as $t) {
					$traceInfo .= '[' . $time . '] ' . $t['file'] . ' (' . $t['line'] . ') ';
					$traceInfo .= $t['class'] . $t['type'] . $t['function'] . '(';
					$traceInfo .= implode(', ', $t['args']);
					$traceInfo .=')<br/>';
				}
				$e['trace'] = $traceInfo;
			} else {
				$e = $error;
			}			
			include template('global','hr_exception');
			die;
		}
	}
	
	public static function handleError($errno, $errstr, $errfile, $errline) {
		if(HRLOO_DEBUG === 1){
				switch ($errno) {
					case E_ERROR:
					case E_USER_ERROR:
						$errorStr = "[$errno] $errstr ".basename($errfile)." 第 $errline 行.";
						echo $errorStr.'<br />';
						break;
					case E_STRICT:
					case E_USER_WARNING:
					case E_USER_NOTICE:
					default:
						$errorStr = "[$errno] $errstr ".basename($errfile)." 第 $errline 行.";
						break;
				}
		}
	}
	
	public static function handleShutdown() {
		//if(($error = error_get_last()) && $error['type'] & DISCUZ_CORE_DEBUG) {
		//	discuz_error::system_error($error['message'], false, true, false);
		//}
	}
	
	
}


/**
 * 控制器基类
 * @author root
 *
 */
class hcontroller{
	private $_session;
	
	/**
	 * 获取当前会话
	 * @return srv_uc_session
	 */
	function _session(){
		if(!$this->_session){
			$this->_session = srv_uc_session::I();
		}
		return $this->_session;
	}
	
	/**
	 * 当前用户是否登录
	 */
	protected function _islogin(){
 		return $this->_session()->islogin();
	}
	/**
	 * 跳转到404页面
	 */
	protected function _404Page(){
		hheaderLocation(HPAGE_404_URL);
	}
	/**
	 * 跳转到错误页面	 
	 * @param $ex Exception
	 */
	protected function _errorPage($ex=null){		
		hheaderLocation(HPAGE_ERROR_URL);
	}
	/**
	 * 未登录跳转
	 */
	protected function _redirect2login($redirect=true)
	{
		$loginurl = hlogin_url();
		Header("Location:".$loginurl);
		exit;
	}
	
	
	/**
	 * 获取当前用户信息
	 */
	protected function _user(){
		return $this->_session()->user();
	}
	
	/**
	 * 获取当前UID
	 * @return int
	 */
	protected function _uid(){
		$u = $this->_user();
		if($u) return $u['uid'];
		return false;
	}
	
	/**
	 * 获取页码
	 * @param int $key
	 * @return number 页码从1开始
	 */
	protected function _page($key='page'){
		$p = intval($_GET[$key]);
		if(!$p || $p < 1) return 1;
		return $p;
	}
	
	/**
	 * 获取整型ID
	 * @param unknown_type $key
	 * @param unknown_type $def
	 * @return unknown|number
	 */
	protected function _id($key='id',$def=0){
		$gp = $_GET[$key]?$_GET[$key]:$_POST[$key];
		if(!$gp) return $def;
		return intval($gp);
	}
	/**
	 * 输出jsonp
	 * @param int $result 0:成功，1：失败，100：未登录，99：未知异常
	 * @param string $msg
	 * @param array $data 
	 * @param string $jsoncallback 回调方法名称
	 */	
	protected function _return_jsonp($result,$msg,$data,$jsoncallback=''){		
		$json = json_encode(array('result'=>$result,'msg'=>$msg,'data'=>$data));
		if(!$jsoncallback){
			$jsoncallback=$_GET['jsoncallback'];
		}
		die(strip_tags($jsoncallback).'('.$json.')');
	}/**
	 * 已知异常，返回错误信息 $result 默认为1, 可自定义
	 * @param unknown_type $msg
	 * @param unknown_type $data
	 * @param string $jsoncallback 回调方法名称
	 */
	protected function _failed_jsonp($msg='操作失败',$result=1,$data=null,$jsoncallback=''){
		$this->_return_jsonp($result,$msg,$data,$jsoncallback);
	}	
	/**
	 * 未知异常 resutl返回 99
	 * @param string $msg
	 * @param array|mixed $data
	 * @param  string $jsoncallback 回调方法名称
	 */
	protected function _failed_unknow_jsonp($jsoncallback='',$msg="服务器出现未知错误",$data=null)
	{
		return $this->_return_jsonp(99, $msg, $data,$jsoncallback);
	}
	/**
	 * 未登录异常 result 返回 100
	 * @param string $msg
	 * @param array|mixed $data
	 * @param  string $jsoncallback 回调方法名称
	 */
	protected function _failed_notlogin_jsonp($jsoncallback='',$msg="你还没有登录",$data=null)
	{		
		return $this->_return_jsonp(100, $msg, $data,$jsoncallback);
	}
	/**
	 * 成功返回 result 返回 0
	 * @param string $jsoncallback 回调方法名称
	 * @param unknown_type $msg
	 * @param unknown_type $data
	 */
	protected function _success_jsonp($jsoncallback='',$msg="成功",$data=null)
	{
		return $this->_return_jsonp(0, $msg, $data,$jsoncallback);
	}
	/**
	 * 返回JSON, result 自己定义
	 * @param int $result
	 * @param string $msg
	 * @param array|mixed $data
	 * @param bool $echo_exit 如果为true则echo然后exit返回，如果为false则返回JSON串
	 */
	protected function _return_json($result,$msg,$data=null,$echo_exit=true){
		$json = json_encode(array('result'=>$result,'msg'=>$msg,'data'=>$data));
		if($echo_exit){
			echo $json;
			exit;
		}
		return $json;
	}	
	/**
	 * 已知异常，返回错误信息 $result 默认为1, 可自定义
	 * @param unknown_type $msg
	 * @param unknown_type $data
	 * @param unknown_type $echo_exit
	 */
	protected function _failed($msg='操作失败',$result=1,$data=null,$echo_exit=true){
		$this->_return_json($result,$msg,$data,$echo_exit);
	}	
	/**
	 * 未知异常 resutl返回 99
	 * @param string $msg
	 * @param array|mixed $data
	 * @param  bool $echo_exit 如果为true则echo然后exit返回，如果为false则返回JSON串
	 */
	protected function _failed_unknow($echo_exit=true,$msg="服务器出现未知错误",$data=null)
	{
		return $this->_return_json(99, $msg, $data,$echo_exit);
	}
	/**
	 * 未登录异常 result 返回 100
	 * @param string $msg
	 * @param array|mixed $data
	 * @param  bool $echo_exit 如果为true则echo然后exit返回，如果为false则返回JSON串
	 */
	protected function _failed_notlogin($echo_exit=true,$msg="你还没有登录",$data=null)
	{		
		return $this->_return_json(100, $msg, $data,$echo_exit);
	}
	/**
	 * 需要验证码
	 * @param unknown_type $echo_exit
	 * @param unknown_type $msg
	 * @param unknown_type $data
	 */
	protected function _failed_needvcode($echo_exit=true,$msg="验证码错误",$data=null)
	{		
		return $this->_return_json(101, $msg, $data,$echo_exit);
	}
	protected function _chkvcode($module,$postName='hrvcode'){
		//TODO:判断是否需要验证码
		$needvcode=true;
		if($needvcode){
			if(!$_POST[$postName]){			
				$this->_failed_needvcode(true,'请输入验证码');
			}
			core::setMemSessionHandler();
			session_start ();
			$vfc = new verifycode();
			if(!$vfc->verify($_POST[$postName])){
				$this->_failed_needvcode();
			}
		}
	}
	/**
	 * 成功返回 result 返回 0
	 * @param unknown_type $echo_exit
	 * @param unknown_type $msg
	 * @param unknown_type $data
	 */
	protected function _success($echo_exit=true,$msg="成功",$data=null)
	{
		return $this->_return_json(0, $msg, $data,$echo_exit);
	}
	/**
	 * 引入片段模板，支持参数传入
	 * @param 模块名 $module
	 * @param 模板名 $tpl
	 * @param array $data
	 */
	protected function _widget($module,$tpl,$data,$return=false){
		if($return){
			ob_start();
			ob_implicit_flush(false);
		}
		if($module&&$tpl){
			if($data){
				extract($data,EXTR_OVERWRITE);
			}
			include template($module,$tpl);
			if($return){
				return ob_get_clean();
			}
		}
	}
	/**
	 * 输出xml格式数据
	 * @param 模块名 $module
	 * @param 模板名 $tpl
	 * @param array $tpldata
	 * @param int $errnum
	 * @param string $errmsg
	 */
	protected function _return_xml($module,$tpl,$tpldata,$errnum,$errmsg,$data){		
		$hrloo_xml_data=json_encode($data);
		include template('global','header_ajax');
		$this->_widget($module, $tpl, $tpldata);
		include template('global','footer_ajax');
	}
	/**
	 * 输出xml格式数据
	 * @param unknown_type $errnum 默认为 1
	 * @param unknown_type $errmsg 默认为操作失败
	 * @param unknown_type $module
	 * @param unknown_type $tpl
	 * @param unknown_type $tpldata
	 */
	protected function _failed_xml($errmsg='操作失败',$errnum=1,$module=null,$tpl=null,$tpldata=null,$data=null){
		return $this->_return_xml($module,$tpl,$tpldata,$errnum, $errmsg,$data);
	}
	/**
	 * 输出xml格式数据 errnum为99
	 * @param unknown_type $module
	 * @param unknown_type $tpl
	 * @param unknown_type $tpldata
	 * @param unknown_type $errmsg
	 */
	protected function _failed_unknow_xml($module=null,$tpl=null,$tpldata=null,$errmsg='服务器出现未知错误',$data=null){
		return $this->_return_xml($module,$tpl,$tpldata,99, $errmsg,$data);
	}
	/**
	 * 输出xml格式数据 errnum为100
	 * @param unknown_type $module
	 * @param unknown_type $tpl
	 * @param unknown_type $tpldata
	 * @param unknown_type $errmsg
	 */
	protected function _failed_notlogin_xml($module=null,$tpl=null,$tpldata=null,$errmsg="你还没有登录",$data=null){
		return $this->_return_xml($module,$tpl,$tpldata,100, $errmsg,$data);
	}
	/**
	 * 输出xml格式数据 errnum为0
	 * @param unknown_type $module
	 * @param unknown_type $tpl
	 * @param unknown_type $tpldata
	 * @param unknown_type $msg
	 */
	protected function _success_xml($module,$tpl,$tpldata,$errmsg="成功",$errnum=0,$data=null){
		return $this->_return_xml($module,$tpl,$tpldata,$errnum,$errmsg,$data);
	}
}

class hmodel{
	
}


